06. 关于 OOP 的几个注意事项

关于 OOP 的注意事项

关于 OOP 的注意事项

Set 和 Get 方法

上一部分的视频提到在 Python 里访问属性与在 Java 和 C++ 等其他语言中不太一样。这部分将深入介绍这方面的知识。

shirt 类有一个更改衬衫价格的方法: shirt_one.change_price(20) 。在 Python 里,你还可以通过以下语法更改属性的值:

shirt_one.price = 10
shirt_one.price = 20
shirt_one.color = 'red'
shirt_one.size = 'M'
shirt_one.style = 'long_sleeve'

这段代码会直接访问并更改 price、color、size 和 style 属性。很多其他语言在使用时,都不推荐或者禁用直接访问属性, 但是 Python 允许直接访问属性 。常用面向对象编程规范是使用方法访问属性或更改属性值。这些方法称为 set 和 get 方法或 setter 和 getter 方法。

get 方法用于获取属性值。set 方法用于更改属性值。对于 Shirt 类来说,代码如下所示:

class Shirt:

    def __init__(self, shirt_color, shirt_size, shirt_style, shirt_price):
        self._price = shirt_price

    def get_price(self):
      return self._price

    def set_price(self, new_price):
      self._price = new_price

实例化和使用对象如下所示:

shirt_one = Shirt('yellow', 'M', 'long-sleeve', 15)
print(shirt_one.get_price())
shirt_one.set_price(10)

在类定义里,price 前面的下划线是比较有争议的 Python 规范。在 C++ 或 Java 等其他语言里,price 会被明确标记为私有变量,禁止对象直接访问 price 属性,所以 shirt_one._price = 15 也就不可行。但是,Python 不像其他语言那样区分公共变量和私有变量。因此,在 Python 中使用下划线规范和 get 及 set 方法就有一定的争议。

但是,很多 Python 程序员还是会使用 get 和 set 方法开发面向对象程序。如果 Python 本身并不鼓励使用 get 和 set 方法,为何还要使用它们?

根据 Python 规范,price 前面的下划线是告诉程序员只能通过 get 和 set 方法访问 price,而不能使用 shirt_one._price 直接访问 price。但是,程序员依然可以直接访问 price,因为 Python 语言并没有禁止直接访问属性。

重申下,技术上来说,程序员依然可以使用 shirt_one._price = 10 这样的直接访问,代码能运行。但是像这样直接访问 price 并不符合 Shirt 类的设计意图和使用规范。

正如之前在这门课程中提到的,set 和 get 方法的优势之一是可以向用户隐藏实现代码。也许变量一开始编写为列表,之后变成了字典。借助 set 和 get 方法,你可以轻松地更改获取该变量的方式。如果没有 set 和 get 方法,你需要找到直接访问该变量的所有代码并更改代码。

要详细了解 Python 中的 set 和 get 方法,请访问此 Python 教程网站

关于属性的注意事项

与使用方法访问属性相比,直接访问属性有很多劣势。

对于面向对象编程来说,Python 的编写规范比其他编程语言要宽松。例如之前提到的,在 C++ 等语言中,你可以明确设置禁止直接更改或访问属性值。Python 就没有这样的设定。

那么,为何通过方法更改值比直接更改值更好?因为,从长远来看,通过方法更改值能使代码更灵活。比如,如果计量单位变了,该怎么办?假设某商店的售卖商品一开始采用的是美元货币,现在需要采用欧元?举个例子:

美元与欧元换算示例

如果直接更改属性值,你就需要找到所有使用美元的代码,例如:

shirt_one.price = 10 # US dollars

然后手动换算并修改为欧元

shirt_one.price = 8 # Euros

但是,如果你使用了方法,则只需更改方法,自动从美元换算成欧元。

def change_price(self, new_price):
    self.price = new_price * 0.81 # convert dollars to Euros

shirt_one.change_price(10)

如果你刚开始学习面向对象编程,你可能还不会涉及到这个方面,但是,如果你决定深入学习,尤其是 C++ 或 Java 等其他语言,这个方面的考量对你的代码编写就会显得非常重要。

模块化代码

所有代码都在 Jupyter Notebook 里,例如,在之前的练习中,有个加载 Shirt 类的代码单元格,让你能够在整个 notebook 的后续部分访问 Shirt 类。但是,如果你要开发软件程序,则需要模块化代码。

你需要将 Shirt 类放入单独的 Python 脚本中,并取个名称,例如 shirt.py。然后在另一个 Python 脚本里,使用以下这行代码导入 Shirt 类:
from shirt import Shirt .

目前你可以在 Jupyter notebook 中完成练习。但是之后你需要学会将面向对象代码模块化为单独的文件。